/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.diplomka.datalayer.daoimpl;

import cz.muni.fi.diplomka.datalayer.dao.CityDao;
import cz.muni.fi.diplomka.datalayer.entity.CityEntity;
import cz.fi.muni.diplomka.common.Coordinates;
import cz.muni.fi.diplomka.datalayer.util.DbConnector;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Jakub Kutil
 */
public class CityDaoImpl implements CityDao {

    private Connection con = null;
    private PreparedStatement ps = null;
    private ResultSet rs = null;

    public CityDaoImpl() {
    }

    @Override
    public void addCity(CityEntity cityEntity) {
        if (cityEntity == null) {
            throw new IllegalArgumentException("CityEntity can not be null");
        }
        try {
            con = DbConnector.getDBConnection();
            String insert = "INSERT INTO city (player_id, name, x_coordinate, y_coordinate) VALUES (?,?,?,?)";
            ps = con.prepareStatement(insert);

            ps.setLong(1, cityEntity.getPlayerId());
            ps.setString(2, cityEntity.getName());
            ps.setInt(3, cityEntity.getCoordinates().getX_coordinate());
            ps.setInt(4, cityEntity.getCoordinates().getY_coordinate());

            ps.executeUpdate();

            rs = ps.getGeneratedKeys();
            rs.next();

        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
    }

    @Override
    public void editCity(CityEntity cityEntity) {
        if (cityEntity == null) {
            throw new IllegalArgumentException("CityEntity can not be null");
        }
        try {
            con = DbConnector.getDBConnection();
            String update = "UPDATE city SET name=?, x_coordinate=?, y_coordinate=? WHERE id=?";

            ps = con.prepareStatement(update);

            ps.setString(1, cityEntity.getName());
            ps.setInt(2, cityEntity.getCoordinates().getX_coordinate());
            ps.setInt(3, cityEntity.getCoordinates().getY_coordinate());
            ps.setLong(4, cityEntity.getId());

            ps.executeUpdate();
            
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
    }
    
    @Override
    public CityEntity getCityAtPosition(Coordinates coordinates) {
        if (coordinates == null) {
            throw new IllegalArgumentException("Coordinates can not be null");
        }
        CityEntity cityEntity = new CityEntity();

        try {
            con = DbConnector.getDBConnection();
            String getCityAtPosition = "SELECT * FROM city WHERE x_coordinate=? AND y_coordinate=?";

            ps = con.prepareStatement(getCityAtPosition);
            ps.setInt(1, coordinates.getX_coordinate());
            ps.setInt(2, coordinates.getY_coordinate());

            rs = ps.executeQuery();

            while (rs.next()) {
                cityEntity.setId(rs.getLong("id"));
                cityEntity.setPlayerId(rs.getLong("player_id"));
                cityEntity.setName(rs.getString("name"));
                Coordinates c = new Coordinates();
                c.setX_coordinate(rs.getInt("x_coordinate"));
                c.setY_coordinate(rs.getInt("y_coordinate"));
                cityEntity.setCoordinates(c);
            }
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return cityEntity;
    }

    @Override
    public List<CityEntity> getCitiesOfPlayer(Long playerId) {
        if (playerId == null) {
            throw new IllegalArgumentException("PlayerID can not be null");
        }
        List<CityEntity> cities = new ArrayList<>();

        try {
            con = DbConnector.getDBConnection();
            String getCityOfPlayer = "SELECT * FROM city WHERE player_id=?";

            ps = con.prepareStatement(getCityOfPlayer);
            ps.setLong(1, playerId);

            rs = ps.executeQuery();

            while (rs.next()) {
                CityEntity cityEntity = new CityEntity();
                cityEntity.setId(rs.getLong("id"));
                cityEntity.setPlayerId(rs.getLong("player_id"));
                cityEntity.setName(rs.getString("name"));
                Coordinates c = new Coordinates();
                c.setX_coordinate(rs.getInt("x_coordinate"));
                c.setY_coordinate(rs.getInt("y_coordinate"));
                cityEntity.setCoordinates(c);
                cities.add(cityEntity);
            }
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return cities;
    }

    @Override
    public List<CityEntity> getAllCities() {
        List<CityEntity> cityEntityList = new ArrayList<CityEntity>();

        try {
            con = DbConnector.getDBConnection();
            String getAllCities = "SELECT * FROM city";

            ps = con.prepareStatement(getAllCities);

            rs = ps.executeQuery();

            while (rs.next()) {
                CityEntity cityEntity = new CityEntity();
                cityEntity.setId(rs.getLong("id"));
                cityEntity.setPlayerId(rs.getLong("player_id"));
                cityEntity.setName(rs.getString("name"));
                Coordinates c = new Coordinates();
                c.setX_coordinate(rs.getInt("x_coordinate"));
                c.setY_coordinate(rs.getInt("y_coordinate"));
                cityEntity.setCoordinates(c);

                cityEntityList.add(cityEntity);
            }
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return cityEntityList;
    }

    @Override
    public CityEntity getCityById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("ID can not be null");
        }
        CityEntity cityEntity = new CityEntity();

        try {
            con = DbConnector.getDBConnection();
            String getCityAtPosition = "SELECT * FROM city WHERE id=?";

            ps = con.prepareStatement(getCityAtPosition);
            ps.setLong(1, id);

            rs = ps.executeQuery();

            while (rs.next()) {
                cityEntity.setId(rs.getLong("id"));
                cityEntity.setPlayerId(rs.getLong("player_id"));
                cityEntity.setName(rs.getString("name"));
                Coordinates c = new Coordinates();
                c.setX_coordinate(rs.getInt("x_coordinate"));
                c.setY_coordinate(rs.getInt("y_coordinate"));
                cityEntity.setCoordinates(c);
            }
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return cityEntity;
    }

    @Override
    public CityEntity getCityByName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Name can not be null");
        }

        CityEntity cityEntity = new CityEntity();

        try {
            con = DbConnector.getDBConnection();
            String getCityAtPosition = "SELECT * FROM city WHERE name=?";

            ps = con.prepareStatement(getCityAtPosition);
            ps.setString(1, name);

            rs = ps.executeQuery();

            while (rs.next()) {
               cityEntity.setId(rs.getLong("id"));
                cityEntity.setPlayerId(rs.getLong("player_id"));
                cityEntity.setName(rs.getString("name"));
                Coordinates c = new Coordinates();
                c.setX_coordinate(rs.getInt("x_coordinate"));
                c.setY_coordinate(rs.getInt("y_coordinate"));
                cityEntity.setCoordinates(c);
            }
        } catch (SQLException ex) {
            Logger.getLogger(CityDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            DbConnector.closeConnection(rs, ps, con);
        }
        return cityEntity;
    }
}
